home *** CD-ROM | disk | FTP | other *** search
- //////////
- //
- // File: MakeEffectSlideShow.c
- //
- // Contains: QuickTime video effect support for QuickTime movies and still images.
- //
- // Written by: Tim Monroe
- // Based (heavily!) on the MakeEffectSlideShow code written by Sam Bushell.
- //
- // Copyright: © 1997-1999 by Apple Computer, Inc., all rights reserved.
- //
- // Change History (most recent first):
- //
- // <7> 03/03/99 rtm added support for MakeImageDescriptionForEffect (QT 4.0 and later)
- // <6> 03/12/98 rtm added global flag gDoneWithDialog to fix Windows dialog box problems
- // <5> 02/28/98 rtm revised event/message handling following QTShowEffect.c
- // <4> 08/01/98 rtm sync'ed with latest code from Sam: reworked QTEffects_GetFirstVideoTrackInMovie
- // to use GetMovieIndTrackType
- // <3> 11/24/97 rtm reworked event-loop processing: changed QTEffects_DoMakeEffectSlideShowMovieForFiles into
- // QTEffects_DisplayDialogForSources and QTEffects_RespondToDialogSelection
- // <2> 11/21/97 rtm further work
- // <1> 11/06/97 rtm first file; integrated existing code with shell framework;
- // added endian macros where appropriate
- //
- // This application takes the video tracks from two or more movies, asks
- // the user to select a 2-source effect, and makes a slide show movie
- // which uses the effect to switch from one video track to the next.
- //
- // Short video tracks are scaled up to a minimum length, and we can import
- // all sorts of graphical image formats as movies, so you can use this to
- // generate a slide show movie from still images -- or even a collection
- // of stills and movies.
- //
- // Try it out: drag a bunch of JPEG files of the same size onto the application icon.
- // Alternatively, launch the application and then choose them from the Test... menu.
- //
- //////////
-
- // header files
- #include "MakeEffectSlideShow.h"
-
- // global variables
- QTParameterDialog gEffectsDialog = 0L;
- QTAtomContainer gEffectSample = 0; // effects sample
- QTAtomContainer gEffectList = 0;
- PicHandle gPosterA = NULL;
- PicHandle gPosterB = NULL;
- Movie gSrcMovies[kMaxNumSources];
- Track gSrcTracks[kMaxNumSources];
- UInt16 gSpecCount = 0;
- FSSpec gSpecList[kMaxNumSources];
- Boolean gDoneWithDialog = false; // are we done using the effects parameters dialog box?
-
-
- //////////
- //
- // QTEffects_GetFirstVideoTrackInMovie
- // Return, through the theTrack parameter, the first video track in the specified movie.
- //
- // Actually, we look for the first track that has the kCharacteristicCanSendVideo characteristic,
- // so we can apply effects to MPEG or QD3D tracks as well.
- //
- // If no such track is found, return invalidTrack as the function result.
- //
- //////////
-
- OSErr QTEffects_GetFirstVideoTrackInMovie (Movie theMovie, Track *theTrack)
- {
- *theTrack = GetMovieIndTrackType(theMovie, 1, kCharacteristicCanSendVideo, movieTrackCharacteristic | movieTrackEnabledOnly);
-
- if (*theTrack == NULL)
- return(invalidTrack);
-
- return(noErr);
- }
-
-
- //////////
- //
- // QTEffects_GetPosterPictFromFirstVideoTrackInMovieFile
- // Get the poster picture for the first video track in the specified movie file.
- //
- //////////
-
- PicHandle QTEffects_GetPosterPictFromFirstVideoTrackInMovieFile (FSSpec *theSpec)
- {
- PicHandle myPict = NULL;
- Movie myMovie = NULL;
- Track myTrack = NULL;
- short myRefNum = 0;
- OSErr myErr = noErr;
-
- myErr = OpenMovieFile(theSpec, &myRefNum, fsRdPerm);
- BailError(myErr);
-
- myErr = NewMovieFromFile(&myMovie, myRefNum, NULL, NULL, 0, NULL);
- BailError(myErr);
-
- SetMoviePlayHints(myMovie, hintsHighQuality, hintsHighQuality);
-
- myErr = CloseMovieFile(myRefNum);
- BailError(myErr);
-
- myErr = QTEffects_GetFirstVideoTrackInMovie(myMovie, &myTrack);
- BailNil(myTrack);
-
- myPict = GetTrackPict(myTrack, GetMoviePosterTime(myMovie));
-
- bail:
- if (myMovie != NULL)
- DisposeMovie(myMovie);
-
- return(myPict);
- }
-
-
- //////////
- //
- // QTEffects_CopyPortionOfTrackToTrack
- // Extract a portion of the source track and copy it to the destination track.
- //
- // The parameter theSourcePortions is formed by OR-ing any of the portion constants.
- // For example, to copy the start and middle portions, set theSourcePortions to (eStartPortion | eMiddlePortion).
- //
- // We assume that the track time scale is kTimeScale; we also assume that the track has been scaled
- // so that it is at least kMinimumDuration long.
- //
- //////////
-
- OSErr QTEffects_CopyPortionOfTrackToTrack (Track theSourceTrack, UInt16 theSourcePortions, Track theDestTrack, TimeValue theDestStartTime, TimeValue *theDestDuration)
- {
- TimeValue mySourceTrackDuration;
- TimeValue mySourceSegmentStart, mySourceSegmentEnd, mySourceSegmentDuration;
- OSErr myErr = noErr;
-
- mySourceTrackDuration = GetTrackDuration(theSourceTrack);
-
- if (theSourcePortions & eStartPortion)
- mySourceSegmentStart = 0;
- else if (theSourcePortions & eMiddlePortion)
- mySourceSegmentStart = kEffectDuration;
- else
- mySourceSegmentStart = mySourceTrackDuration - kEffectDuration;
-
- if (theSourcePortions & eFinishPortion)
- mySourceSegmentEnd = mySourceTrackDuration;
- else if (theSourcePortions & eMiddlePortion)
- mySourceSegmentEnd = mySourceTrackDuration - kEffectDuration;
- else
- mySourceSegmentEnd = kEffectDuration;
-
- mySourceSegmentDuration = mySourceSegmentEnd - mySourceSegmentStart;
-
- myErr = InsertTrackSegment( theSourceTrack,
- theDestTrack,
- mySourceSegmentStart,
- mySourceSegmentDuration,
- theDestStartTime);
-
- *theDestDuration = mySourceSegmentDuration;
-
- return(myErr);
- }
-
-
- //////////
- //
- // QTEffects_DisplayDialogForSources
- // Display the standard effects parameters dialog box for the movies passed in.
- //
- //////////
-
- OSErr QTEffects_DisplayDialogForSources (FSSpec *theSpecList, UInt16 theSpecCount)
- {
- OSErr myErr = noErr;
-
- // make sure that there are enough sources: you can't make an omelette without enough eggs
- if (theSpecCount < 2) {
- myErr = paramErr;
- goto bail;
- }
-
- // assign source count to a global, so QTEffects_RespondToDialogSelection has access to it
- gSpecCount = theSpecCount;
-
- // get a poster frame for the first two movies
- if (theSpecCount >= 1)
- gPosterA = QTEffects_GetPosterPictFromFirstVideoTrackInMovieFile(&theSpecList[0]);
-
- if (theSpecCount >= 2)
- gPosterB = QTEffects_GetPosterPictFromFirstVideoTrackInMovieFile(&theSpecList[1]);
-
- // ask the user to select a two-source effect
-
- myErr = QTNewAtomContainer(&gEffectSample);
- BailError(myErr);
-
- myErr = QTGetEffectsList(&gEffectList, 2, 2, 0); // min == max == 2
- BailError(myErr);
-
- myErr = QTCreateStandardParameterDialog(gEffectList, gEffectSample, 0, &gEffectsDialog);
- BailError(myErr);
-
- // insert poster frames into dialog
- if (gPosterA != NULL) {
- QTParamPreviewRecord pr;
-
- pr.sourcePicture = gPosterA;
- pr.sourceID = 1;
- QTStandardParameterDialogDoAction(gEffectsDialog, pdActionSetPreviewPicture, &pr);
- }
-
- if (gPosterB != NULL) {
- QTParamPreviewRecord pr;
-
- pr.sourcePicture = gPosterB;
- pr.sourceID = 2;
- QTStandardParameterDialogDoAction(gEffectsDialog, pdActionSetPreviewPicture, &pr);
- }
-
- // now, the frontmost window is the standard effects parameter dialog box;
- // on the Mac, we call QTEffects_HandleEffectsDialogEvents in our main event loop
- // to find and process events targeted at the effects parameter dialog box; on Windows,
- // we need to use a different strategy: we install a modeless dialog callback procedure
- // that is called internally by QTML
-
- #if TARGET_OS_WIN32
- gDoneWithDialog = false;
-
- // force the dialog box to be drawn
- {
- EventRecord myEvent = {0};
-
- QTEffects_EffectsDialogCallback(&myEvent, FrontWindow(), 0);
- }
-
- SetModelessDialogCallbackProc(FrontWindow(), (QTModelessCallbackUPP)QTEffects_EffectsDialogCallback);
- QTMLSetWindowWndProc(FrontWindow(), QTEffects_CustomDialogWndProc);
- #endif
-
- bail:
- return(myErr);
- }
-
-
- //////////
- //
- // QTEffects_RespondToDialogSelection
- // If theErr is codecParameterDialogConfirm, make an effects movie.
- // If theErr is userCanceledErr, do any necessary clean up.
- //
- // Construct a movie that links a sequence of image or movie files together with real-time effects.
- // That is, show the first image or movie, transition (fade or whatever) to the second, show the second,
- // transition to the third, and so forth.
- //
- // We use NewMovieFromFile, which will use movie importers or graphics importers as appropriate,
- // so each file we open may end up as either.
- //
- // If a movie has only one sample in its first video track, we assume it's a still image,
- // and use several copies of that sample with different lengths. This is flawed, since the sample
- // could be a tweened 3DMF movie.
- //
- //////////
-
- void QTEffects_RespondToDialogSelection (OSErr theErr)
- {
- Boolean myDialogWasCancelled = false;
- StandardFileReply myReply;
- short myResID = movieInDataForkResID;
- UInt16 myMovieIter;
- short mySrcMovieRefNum = 0;
- Movie myPrevSrcMovie = NULL;
- Track myPrevSrcTrack = NULL;
- Movie myNextSrcMovie = NULL;
- Track myNextSrcTrack = NULL;
- short myDestMovieRefNum = 0;
- Movie myDestMovie = NULL;
- Fixed myDestMovieWidth, myDestMovieHeight;
- ImageDescriptionHandle myDesc = NULL;
- Track videoTrackFX, videoTrackA, videoTrackB;
- Media videoMediaFX, videoMediaA, videoMediaB;
- TimeValue myCurrentDuration = 0;
- TimeValue myReturnedDuration;
- Boolean isFirstTransition = true;
- TimeValue myMediaTransitionDuration;
- TimeValue myMediaFXStartTime, myMediaFXDuration;
- OSType myEffectCode;
- long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile;
- long myLong;
- OSErr myErr = noErr;
-
- // standard parameter box has been dismissed, so remember that fact
- gEffectsDialog = 0L;
-
- myDialogWasCancelled = (theErr == userCanceledErr);
-
- // we're finished with the effect list and movie posters
- QTDisposeAtomContainer(gEffectList);
-
- if (gPosterA != NULL)
- KillPicture(gPosterA);
-
- if (gPosterB != NULL)
- KillPicture(gPosterB);
-
- // when the sign says stop, then stop
- if (myDialogWasCancelled)
- goto bail;
-
- // add atoms naming the sources to gEffectSample
- myLong = EndianU32_NtoB(kSourceOneName);
- QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 1, 0, sizeof(myLong), &myLong, NULL);
-
- myLong = EndianU32_NtoB(kSourceTwoName);
- QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 2, 0, sizeof(myLong), &myLong, NULL);
-
- // extract the 'what' atom to find out what kind of effect it is
- {
- QTAtom myEffectAtom;
- QTAtomID myEffectAtomID;
- long myEffectCodeSize;
- Ptr myEffectCodePtr;
-
- myEffectAtom = QTFindChildByIndex(gEffectSample, kParentAtomIsContainer, kParameterWhatName, kParameterWhatID, &myEffectAtomID);
-
- myErr = QTLockContainer(gEffectSample);
- BailError(myErr);
-
- myErr = QTGetAtomDataPtr(gEffectSample, myEffectAtom, &myEffectCodeSize, &myEffectCodePtr);
- BailError(myErr);
-
- if (myEffectCodeSize != sizeof(OSType)) {
- myErr = paramErr;
- goto bail;
- }
-
- myEffectCode = *(OSType *)myEffectCodePtr; // "tsk"
- myEffectCode = EndianU32_BtoN(myEffectCode); // because the data is read from an atom container
-
- myErr = QTUnlockContainer(gEffectSample);
- BailError(myErr);
- }
-
- // ask the user for the name of the new movie file
- StandardPutFile("\pSave effect movie file as:", "\pUntitled.mov", &myReply);
- if (!myReply.sfGood)
- goto bail; // deal with user cancelling
-
- // create a movie file for the destination movie
- myErr = CreateMovieFile(&myReply.sfFile, FOUR_CHAR_CODE('TVOD'), 0, myFlags, &myDestMovieRefNum, &myDestMovie);
- BailError(myErr);
-
- // open the first file as a movie; call the first movie myPrevSrcMovie
- myErr = OpenMovieFile(&gSpecList[0], &mySrcMovieRefNum, fsRdPerm);
- BailError(myErr);
-
- myErr = NewMovieFromFile(&myPrevSrcMovie, mySrcMovieRefNum, NULL, NULL, 0, NULL);
- BailError(myErr);
-
- myErr = CloseMovieFile(mySrcMovieRefNum);
- BailError(myErr);
-
- // if the movie is shorter than kMinimumDuration, scale it to that length
- SetMovieTimeScale(myPrevSrcMovie, kTimeScale);
- myErr = QTEffects_GetFirstVideoTrackInMovie(myPrevSrcMovie, &myPrevSrcTrack);
- BailNil(myPrevSrcTrack);
-
- if (GetTrackDuration(myPrevSrcTrack) < kMinimumDuration) {
- myErr = ScaleTrackSegment(myPrevSrcTrack, 0, GetTrackDuration(myPrevSrcTrack), kMinimumDuration);
- BailError(myErr);
- }
-
- // find out how big the first movie is; we'll use it as the size of all our tracks
- GetTrackDimensions(myPrevSrcTrack, &myDestMovieWidth, &myDestMovieHeight);
-
- #if USES_MAKE_IMAGE_DESC_FOR_EFFECT
- // create a new sample description for the effect,
- // which is just an image description specifying the effect and its dimensions
- myErr = MakeImageDescriptionForEffect(myEffectCode, &myDesc);
- if (myErr != noErr)
- BailError(myErr);
- #else
- // create a new sample description for the effect,
- // which is just an image description specifying the effect and its dimensions
- myDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription));
- BailNil(myDesc);
-
- (**myDesc).idSize = sizeof(ImageDescription);
- (**myDesc).cType = myEffectCode;
- (**myDesc).hRes = 72L << 16;
- (**myDesc).vRes = 72L << 16;
- (**myDesc).dataSize = 0L;
- (**myDesc).frameCount = 1;
- (**myDesc).depth = 0;
- (**myDesc).clutID = -1;
- #endif
-
- // fill in the fields of the sample description
- (**myDesc).vendor = kAppleManufacturer;
- (**myDesc).temporalQuality = codecNormalQuality;
- (**myDesc).spatialQuality = codecNormalQuality;
- (**myDesc).width = FixRound(myDestMovieWidth);
- (**myDesc).height = FixRound(myDestMovieHeight);
-
- // add three video tracks to the destination movie:
- // - videoTrackFX is where the effects and stills live; it's user-visible.
- // - videoTrackA is where the "source A"s for effects live; it's hidden by the input map
- // - videoTrackB is where the "source B"s for effects live; it's hidden by the input map
- videoTrackFX = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0);
- BailNil(videoTrackFX);
- videoMediaFX = NewTrackMedia(videoTrackFX, VideoMediaType, kTimeScale, NULL, 0);
- BailNil(videoMediaFX);
- myErr = BeginMediaEdits(videoMediaFX);
- BailError(myErr);
-
- videoTrackA = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0);
- BailNil(videoTrackA);
- videoMediaA = NewTrackMedia(videoTrackA, VideoMediaType, kTimeScale, NULL, 0);
- BailNil(videoMediaA);
-
- videoTrackB = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0);
- BailNil(videoTrackB);
- videoMediaB = NewTrackMedia(videoTrackB, VideoMediaType, kTimeScale, NULL, 0);
- BailNil(videoMediaB);
-
- // create the input map
- {
- long myRefIndex1, myRefIndex2;
- QTAtomContainer myInputMap;
- QTAtom myInputAtom;
- OSType myInputType;
-
- QTNewAtomContainer(&myInputMap);
-
- // first input
- if (videoTrackA) {
-
- AddTrackReference(videoTrackFX, videoTrackA, kTrackModifierReference, &myRefIndex1);
- QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex1, 0, 0, NULL, &myInputAtom);
-
- myInputType = EndianU32_NtoB(kTrackModifierTypeImage);
- QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL);
-
- myLong = EndianU32_NtoB(kSourceOneName);
- QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL);
- }
-
- // second input
- if (videoTrackB) {
-
- AddTrackReference(videoTrackFX, videoTrackB, kTrackModifierReference, &myRefIndex2);
- QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex2, 0, 0, NULL, &myInputAtom);
-
- myInputType = EndianU32_NtoB(kTrackModifierTypeImage);
- QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL);
-
- myLong = EndianU32_NtoB(kSourceTwoName);
- QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL);
- }
-
- // set that map
- SetMediaInputMap(GetTrackMedia(videoTrackFX), myInputMap);
-
- QTDisposeAtomContainer(myInputMap);
- }
-
- myCurrentDuration = 0;
-
- #if MAKE_STILL_SECTIONS
- // copy the first sample of the first video track of the first movie to videoTrackFX, with duration kStillDuration.
- myErr = CopyPortionOfTrackToTrack(myPrevSrcTrack, eStartPortion + eMiddlePortion, videoTrackFX, myCurrentDuration, &myReturnedDuration);
- BailError(myErr);
-
- myCurrentDuration += myReturnedDuration;
- #endif
-
- // now process any remaining files
- myMovieIter = 1;
- while (myMovieIter < gSpecCount) {
-
- // open the next file as a movie; call it nextSourceMovie
- myErr = OpenMovieFile(&gSpecList[myMovieIter], &mySrcMovieRefNum, fsRdPerm);
- BailError(myErr);
-
- myErr = NewMovieFromFile(&myNextSrcMovie, mySrcMovieRefNum, NULL, NULL, 0, NULL);
- BailError(myErr);
-
- // we're done with the movie file, so close it
- myErr = CloseMovieFile(mySrcMovieRefNum);
- BailError(myErr);
-
- // if the movie is shorter than kMinimumDuration, scale it to that length
- SetMovieTimeScale(myNextSrcMovie, kTimeScale);
- myErr = QTEffects_GetFirstVideoTrackInMovie(myNextSrcMovie, &myNextSrcTrack);
- BailNil(myNextSrcTrack);
-
- if (GetTrackDuration(myNextSrcTrack) < kMinimumDuration) {
- myErr = ScaleTrackSegment(myNextSrcTrack, 0, GetTrackDuration(myNextSrcTrack), kMinimumDuration);
- BailError(myErr);
- }
-
- // create a transition effect from the previous source movie's first video sample to the next source movie's first video sample
- // (the effect should have duration kEffectDuration);
- // this involves adding one sample to each of the three video tracks:
-
- // sample from previous source movie -> videoTrackA
- myErr = QTEffects_CopyPortionOfTrackToTrack(myPrevSrcTrack, eFinishPortion, videoTrackA, myCurrentDuration, &myReturnedDuration);
- BailError(myErr);
-
- // sample from next source movie -> videoTrackB
- myErr = QTEffects_CopyPortionOfTrackToTrack(myNextSrcTrack, eStartPortion, videoTrackB, myCurrentDuration, &myReturnedDuration);
- BailError(myErr);
-
- // effect sample -> videoTrackFX
- if (isFirstTransition) {
- myMediaTransitionDuration = myReturnedDuration;
- myMediaFXStartTime = GetMediaDuration(videoMediaFX);
- myErr = AddMediaSample(videoMediaFX, gEffectSample, 0, GetHandleSize(gEffectSample), myMediaTransitionDuration, (SampleDescriptionHandle)myDesc, 1, 0, NULL);
- BailError(myErr);
-
- myMediaFXDuration = GetMediaDuration(videoMediaFX) - myMediaFXStartTime;
- isFirstTransition = false;
- }
-
- myErr = InsertMediaIntoTrack(videoTrackFX, myCurrentDuration, myMediaFXStartTime, myMediaFXDuration, FixRatio(myReturnedDuration, myMediaTransitionDuration));
- BailError(myErr);
-
- myCurrentDuration += myReturnedDuration;
-
- #if MAKE_STILL_SECTIONS
- // copy the first video sample of myNextSrcMovie to videoTrackFX, with duration kStillDuration.
- myErr = QTEffects_CopyPortionOfTrackToTrack(myNextSrcTrack, eMiddlePortion + (myMovieIter + 1 == theSpecCount) ? eFinishPortion : 0, videoTrackFX, myCurrentDuration, &myReturnedDuration);
- BailError(myErr);
-
- myCurrentDuration += myReturnedDuration;
- #endif // MAKE_STILL_SECTIONS
-
- // dispose of previous source movie.
- DisposeMovie(myPrevSrcMovie);
-
- myPrevSrcMovie = myNextSrcMovie;
- myPrevSrcTrack = myNextSrcTrack;
- myNextSrcMovie = NULL;
- myNextSrcTrack = NULL;
-
- myMovieIter++;
- } // while
-
- myErr = EndMediaEdits(videoMediaFX);
- BailError(myErr);
-
- myErr = AddMovieResource(myDestMovie, myDestMovieRefNum, &myResID, "\pMovie 1");
- BailError(myErr);
-
- CloseMovieFile(myDestMovieRefNum);
-
- if (myPrevSrcMovie != NULL)
- DisposeMovie(myPrevSrcMovie);
-
- DisposeMovie(myDestMovie);
-
- bail:
- QTDisposeAtomContainer(gEffectSample);
- DisposeHandle((Handle)myDesc);
-
- return;
- }
-
-
- #if TARGET_OS_WIN32
- //////////
- //
- // QTEffects_EffectsDialogCallback
- // This function is called by QTML when it processes events for the standard or custom effects parameter dialog box.
- //
- //////////
-
- static void QTEffects_EffectsDialogCallback (EventRecord *theEvent, DialogRef theDialog, DialogItemIndex theItemHit)
- {
- QTParamDialogEventRecord myRecord;
-
- myRecord.theEvent = theEvent;
- myRecord.whichDialog = theDialog;
- myRecord.itemHit = theItemHit;
-
- //
- QTStandardParameterDialogDoAction(gEffectsDialog, pdActionModelessCallback, &myRecord);
-
- // see if the event is meant for the effects parameter dialog box
- QTEffects_HandleEffectsDialogEvents(theEvent, theItemHit);
- }
-
-
- //////////
- //
- // QTEffects_CustomDialogWndProc
- // Handle messages for the custom effects parameters dialog box.
- //
- //////////
-
- LRESULT CALLBACK QTEffects_CustomDialogWndProc (HWND theWnd, UINT theMessage, UINT wParam, LONG lParam)
- {
- EventRecord myEvent = {0};
-
- if (!gDoneWithDialog && (theMessage == 0x7FFF))
- QTEffects_EffectsDialogCallback(&myEvent, GetNativeWindowPort(theWnd), 0);
-
- return(DefWindowProc(theWnd, theMessage, wParam, lParam));
- }
- #endif
-
-
- //////////
- //
- // QTEffects_HandleEffectsDialogEvents
- // Process events that might be targeted at the standard effects parameter dialog box.
- // Return true if the event was completely handled.
- //
- //////////
-
- Boolean QTEffects_HandleEffectsDialogEvents (EventRecord *theEvent, DialogItemIndex theItemHit)
- {
- Boolean isHandled = false;
- OSErr myErr = noErr;
-
- // pass the event to the standard effects parameter dialog box handler
- myErr = QTIsStandardParameterDialogEvent(theEvent, gEffectsDialog);
-
- // the result from QTIsStandardParameterDialogEvent tells us how to respond next
- switch (myErr) {
-
- case codecParameterDialogConfirm:
- case userCanceledErr:
- // the user clicked the OK or Cancel button; dismiss the dialog box and respond accordingly
- gDoneWithDialog = true;
- QTDismissStandardParameterDialog(gEffectsDialog);
- QTEffects_RespondToDialogSelection(myErr);
- gEffectsDialog = 0L;
- isHandled = true;
- break;
-
- case noErr:
- // the event was completely handled by QTIsStandardParameterDialogEvent
- isHandled = true;
- break;
-
- case featureUnsupported:
- // the event was not handled by QTIsStandardParameterDialogEvent;
- // let the event be processed normally
- isHandled = false;
- break;
-
- default:
- // the event was not handled by QTIsStandardParameterDialogEvent;
- // do not let the event be processed normally
- isHandled = true;
- break;
- }
-
- return(isHandled);
- }
-
-
- //////////
- //
- // QTEffects_PromptUserForFilesAndMakeEffect
- // Let the user select some movies, then apply the effect to them.
- //
- // If the user cancels the first file-open dialog box, there are zero sources.
- // If the user cancels the second file-open dialog box, there is one source.
- //
- //////////
-
- void QTEffects_PromptUserForFilesAndMakeEffect (void)
- {
- int mySpecCount = 0;
-
- // ask for up to kMaxNumSources movie files;
- // accept early cancels; they just mean there are fewer input movies
- mySpecCount = 0;
- while (mySpecCount < kMaxNumSources) {
- SFTypeList myTypeList;
- StandardFileReply myReply;
-
- myTypeList[0] = MovieFileType;
-
- StandardGetFilePreview(NULL, 1, myTypeList, &myReply);
- if (!myReply.sfGood)
- break; // the user doesn't want any more source movies
-
- // save the FSSpec from the reply information
- gSpecList[mySpecCount] = myReply.sfFile;
-
- mySpecCount++;
- }
-
- QTEffects_DisplayDialogForSources(gSpecList, mySpecCount);
- }
-